from simpy import Environment

from x_pc.core import Device, DeviceCache, DeviceCost
from x_pc.db.sf_data import WorkCenterLoc, WorkCenterLocType


class CenterBiz(DeviceCache):
    """
    工作中心 业务数据
    """
    # 编号
    id: str = None
    # 设备编号
    equ_code: str = None
    # 设备类型
    equ_type: int = None
    # 缓存
    cache_num: int = None
    # 最大同时搬运数
    max_once_operation_num: int = None
    # 是否启用 1启用 2不启用
    enable: int = None
    # 设备区域
    equ_area: str = None

    # 设备位置列表
    loc_list: list[str] = []
    # 设备耗时(work_type, time_cost)
    worktype_time_cost_dict: dict[int, float] = {}

    def __init__(self, kwargs):
        self.loc_list: list[WorkCenterLoc] = []
        self.worktype_time_cost_dict: dict[int, float] = {}
        #
        for key in kwargs:
            if hasattr(self, key):
                setattr(self, key, kwargs[key])

    def cache_nums(self) -> int:
        return self.cache_num


class Center(Device, CenterBiz, DeviceCost):
    """
    工作中心
    """
    category: str = 'center'

    def __init__(self, env: Environment, name: str, kwargs):
        Device.__init__(self, env, name)
        CenterBiz.__init__(self, kwargs)

    def device_type(self):
        return self.equ_type

    def device_code(self):
        return self.equ_code

    def cost(self, work_type: int) -> float:
        """
        耗时
        :param work_type:
        :return:
        """
        if work_type not in self.worktype_time_cost_dict:
            return 99999
        return self.worktype_time_cost_dict[work_type]

    def loc(self) -> list[WorkCenterLoc]:
        """
        位置信息
        :return:
        """
        raise Exception(f'[PC] 根据情况使用 {self.source_loc().__name__} 和 {self.sink_loc.__name__}')

    def source_loc(self) -> WorkCenterLoc:
        """
        源位置
        :return:
        """
        for loc in self.loc_list:
            if loc.loc_type_enum() in (WorkCenterLocType.SOURCE, WorkCenterLocType.SOURCE_SINK):
                return loc

    def sink_loc(self) -> list[WorkCenterLoc]:
        """
        目标位置
        :return:
        """
        return [_ for _ in self.loc_list if
                _.loc_type_enum() in (WorkCenterLocType.SINK, WorkCenterLocType.SOURCE_SINK)]
